import axios from 'axios';
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError, InternalAxiosRequestConfig } from 'axios';
import { showMessage } from './status';
import { IResponse } from './type';
import { getToken } from '/@/utils/auth';
import { TokenPrefix } from '/@/utils/auth';
import { ADMIN_USER_TOKEN, USER_TOKEN, BASE_URL } from '/@/store/constants';

const service: AxiosInstance = axios.create({
  baseURL: BASE_URL,
  timeout: 15000,
});

// axios instance request interceptor
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    const adminToken = localStorage.getItem(ADMIN_USER_TOKEN);
    const userToken = localStorage.getItem(USER_TOKEN);

    if (adminToken) {
      config.headers['admintoken'] = adminToken;
    }
    if (userToken) {
      config.headers['token'] = userToken;
    }

    return config;
  },
  (error: AxiosError) => {
    return Promise.reject(error);
  },
);

// axios instance response interceptor
service.interceptors.response.use(
  (response: AxiosResponse) => {
    if (response.status === 200) {
      if (response.data.code === 0 || response.data.code === 200) {
        return response;
      } else {
        return Promise.reject(response.data);
      }
    } else {
      return Promise.reject(response.data);
    }
  },
  // Request failed
  (error: any) => {
    if (error.response) {
      console.log(`Error response status: ${error.response.status}`);
      console.log(`Error response data: ${error.response.data}`);
    } else {
      console.log(`Error message: ${error.message}`);
    }
    return Promise.reject(error);
  },
);

const request = <T = any>(config: AxiosRequestConfig): Promise<T> => {
  return service
    .request<any, AxiosResponse<IResponse>>(config)
    .then((res: AxiosResponse<IResponse>) => {
      const data = res.data;
      return data as T;
    })
    .catch((err) => {
      return Promise.reject(err);
    });
};

export function get<T = any>(config: AxiosRequestConfig): Promise<T> {
  return request({ ...config, method: 'GET' });
}

export function post<T = any>(config: AxiosRequestConfig): Promise<T> {
  return request({ ...config, method: 'POST' });
}

export default request;

export type { AxiosInstance, AxiosResponse };
